
package ParamValues;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;


public class PVP extends PVC {
	 private static PVC paramValueCollection = null;	 
  private final List<Class<?>> classes = new LinkedList<Class<?>>();
  
  public PVP(Collection<Class<?>> classes) {
   // PalusUtil.checkNull(classes, "The class collection could not be null.");
    this.classes.addAll(classes);
  }
  
  /**
   * Process each annotation and add them to the collection set
   * */
  public PVC processAnnotations() {
    PVC collections = new PVC();
    
    //process each class
    for(Class<?> clazz : classes) {
      Field[] fields = clazz.getDeclaredFields();
      for(Field field : fields) {
        
        //System.out.println(field.toGenericString() + "    " + field.getAnnotations().length);
        
        ParamValue value = field.getAnnotation(ParamValue.class);
        if(value != null) {
          //find it, but need check the validity of the field
          if(!this.isValid(field)) {
            System.err.println("The ParamValue decorated field should be public static!");
            continue;
          }
          //get the value
          Object obj = null;
          try {
            obj = field.get(null);
          } catch (Throwable e) {
        	  System.out.println("Ignore annotated non-primitive, non-string value: " + e);
        	  
          }
          
          //only add primitive or string type
          //add the value to the repository
          if(obj != null && PVC.isPrimitiveOrStringType(obj.getClass())) {
            this.processParamValue(collections, value, obj);
          } else {
            System.out.println("Ignore annotated non-primitive, non-string value: " + obj);
          }
        }
      }
    }
    
    return collections;
  }
  
  /**
   * Add values to the collection
   * */
  private void processParamValue(PVC collections, ParamValue value, Object obj) {
    collections.addParamValue(value, obj);
  }
  
  /**
   * The annotated must be public static
   * */
  private boolean isValid(Field field) {
    int modifier = field.getModifiers();
    return Modifier.isPublic(modifier) && Modifier.isStatic(modifier);
  }
  
  /**
   * A simple test driver
   * */
  public static void main(String[] args) throws ClassNotFoundException {
	
    List<Class<?>> classes = new LinkedList<Class<?>>();
   classes.add(Class.forName("ParamValues.SomeParamValues"));
    PVP processor = new PVP(classes);
    PVC collections = processor.processAnnotations();
    PVP paramValueProcessor = new PVP(classes);
    paramValueCollection = paramValueProcessor.processAnnotations();
    String content = collections.showContent();
    System.out.println(content);
  }
  
}